#ifndef DOMAIN_H
#define DOMAIN_H
#pragma warning(disable:4996)

#include <boost/serialization/access.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>

#include <string>
#include <map>
#include "utils.h"
using namespace std;

//the full data from text
class Record {
	friend ostream & operator << (ostream &, const Record &);
	friend boost::serialization::access;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar & imageFileName;
		ar & metadatas;
		ar & eigenVector;
	}
public :
	string imageFileName;
	vector<double> metadatas;
	vector<unsigned char> eigenVector;
	Record() {}
	Record(string & line) {
		unsigned int metadatasSize = 4;
		unsigned int vectorSize = 128;
		vector<string> strs = split(line, " ");
		vector<string>::iterator str_iter = strs.begin();
		imageFileName = *str_iter;

		metadatas.resize(metadatasSize);
		eigenVector.resize(vectorSize);
		str_iter ++;
		for (unsigned int i = 0; i < metadatasSize; i++) {
			string meta = *str_iter;
			metadatas[i] = atof(meta.c_str());
			str_iter ++;
		}

		for (unsigned int i = 0; i < vectorSize; i++) {
			string vec = *str_iter;
			eigenVector[i] = atoi(vec.c_str());
			str_iter ++;
		}
	}
	~Record() {}
};

//the sub vector info
class SubVector {
	friend boost::serialization::access;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar & startIndex;
		ar & subVectorDim;
	}
public :
	unsigned char startIndex;
	unsigned char subVectorDim;
	SubVector() {}
	SubVector(unsigned char si, unsigned char svd) 
		: startIndex(si), subVectorDim(svd){}
	~SubVector() {}
};

//sub vector L2 norms for each record
class L2Norms {
	friend boost::serialization::access;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version)
	{
		ar & l2norm;
	}
public :
	vector<double> l2norm;
};

class Index {
	friend boost::serialization::access;
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version) {
		ar & indexs;
	}
public :
	map<unsigned int, vector<unsigned int> > indexs;
};
#endif